package org.smartboot.license.server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.UUID;

public class DeviceIdentifier {

    public static String generateUniqueDeviceIdentifier() {
        try {
            // 获取CPU序列号
            String cpuSerial = getCpuSerialNumber();
            // 获取主板序列号
            String baseBoardSerial = getBaseBoardSerialNumber();
            // 获取磁盘序列号
            String diskSerial = getDiskSerialNumber();
            // 组合硬件信息生成唯一标识符
            return generateSHA256Hash(cpuSerial + baseBoardSerial + diskSerial);
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
            return UUID.randomUUID().toString(); // 返回一个新的UUID作为备选标识符
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }

    private static String getCpuSerialNumber() throws IOException, InterruptedException {
        String cmd = "wmic cpu get ProcessorId";
        return executeCommand(cmd);
    }

    private static String getBaseBoardSerialNumber() throws IOException, InterruptedException {
        String cmd = "wmic baseboard get SerialNumber";
        return executeCommand(cmd);
    }

    private static String getFirstMacAddress() throws IOException, InterruptedException {
        String cmd = "wmic nic get MACAddress";
        String output = executeCommand(cmd);
        // wmic输出多行，取第一行的MAC地址
        String[] lines = output.split("\\r?\\n");
        return lines.length > 0 ? lines[0].trim() : "";
    }

    private static String getDiskSerialNumber() throws IOException, InterruptedException {
        String cmd = "wmic diskdrive get SerialNumber";
        return executeCommand(cmd);
    }

    private static String executeCommand(String cmd) throws IOException, InterruptedException {
        Process process = Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c", cmd});
        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        StringBuilder output = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            output.append(line);
        }
        process.waitFor();
        return filterEmptyStrings(output.toString().split(" "))[1].trim();
    }

    public static String[] filterEmptyStrings(String[] strings) {
        return Arrays.stream(strings)
                .filter(s -> s != null && !s.trim().isEmpty())
                .toArray(String[]::new);
    }

    private static String generateSHA256Hash(String input) throws NoSuchAlgorithmException {
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        byte[] hash = digest.digest(input.getBytes(StandardCharsets.UTF_8));
        StringBuilder hexString = new StringBuilder(2 * hash.length);
        for (int i = 0; i < hash.length; i++) {
            String hex = Integer.toHexString(0xff & hash[i]);
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
        }
        return hexString.toString();
    }

    public static void main(String[] args) {
        String uniqueDeviceIdentifier = generateUniqueDeviceIdentifier();
        System.out.println("Unique Device Identifier: " + uniqueDeviceIdentifier);
    }
}